<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-icons/iron-icons.html">
<link rel="import" href="../marked-element/marked-element.html">
<link rel="import" href="../paper-icon-button/paper-icon-button.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="../paper-styles/shadow.html">
<link rel="import" href="../prism-element/prism-highlighter.html">
<link rel="import" href="../prism-element/prism-theme-default.html">

<!--
`demo-snippet` is a helper element that displays the source of a code snippet and
its rendered demo. It can be used for both native elements and
Polymer elements.

    Example of a native element demo

        <demo-snippet>
          <template>
            <input type="date">
          </template>
        </demo-snippet>

    Example of a Polymer <paper-checkbox> demo

        <demo-snippet>
          <template>
            <paper-checkbox>Checkbox</paper-checkbox>
            <paper-checkbox checked>Checkbox</paper-checkbox>
          </template>
        </demo-snippet>

### Styling

The following custom properties and mixins are available for styling:

Custom property | Description | Default
----------------|-------------|----------
`--demo-snippet` | Mixin applied to the entire element | `{}`
`--demo-snippet-demo` | Mixin applied to just the demo section | `{}`
`--demo-snippet-code` | Mixin applied to just the code section | `{}`

@element demo-snippet
@demo demo/index.html
-->

<dom-module id="demo-snippet">
  <template>
    <style is="custom-style" include="prism-theme-default"></style>
    <style>
      :host {
        display: block;
        @apply(--shadow-elevation-2dp);
        @apply(--demo-snippet);
      }

      .demo {
        border-bottom: 1px solid var(--google-grey-300);
        background-color: white;
        margin: 0;
        padding: 20px;
        @apply(--demo-snippet-demo);
      }

      .code {
        padding: 20px;
        margin: 0;
        background-color: var(--google-grey-100);
        font-size: 13px;
        overflow: auto;
        @apply(--demo-snippet-code);
      }

      .code > pre {
        margin: 0;
        padding: 0 0 10px 0;
      }

      .code-container {
        position: relative;
      }

      paper-icon-button {
        position: absolute;
        top: 0;
        right: 0px;
      }

    </style>

    <prism-highlighter></prism-highlighter>

    <div class="demo">
      <content id="content"></content>
    </div>

    <div class="code-container">
      <marked-element markdown=[[_markdown]] id="marked">
        <div class="markdown-html code" id="code"></div>
      </marked-element>
      <paper-icon-button
          id="copyButton"
          icon="content-copy"
          title="copy to clipboard"
          on-tap="_copyToClipboard">
      </paper-icon-button>
    </div>
  </template>

  <script>
    'use strict';

    Polymer({
      is: 'demo-snippet',

      properties: {
        _markdown: {
          type: String,
          value: ''
        }
      },

      attached: function() {
        var template = Polymer.dom(this).queryDistributedElements('template')[0];

        // If there's no template, render empty code.
        if (!template) {
          this._markdown = '```\n```';
          return;
        }

        var snippet = this.$.marked.unindent(template.innerHTML);

        // Boolean properties are displayed as checked="", so remove the ="" bit.
        snippet = snippet.replace(/=""/g, '');

        this._markdown = '```\n' + snippet + '\n' + '```';

        // Stamp the template.
        if (!template.hasAttribute('is')) {
          Polymer.dom(this).appendChild(document.importNode(template.content, true));
        }
      },

      _copyToClipboard: function() {
        // From https://github.com/google/material-design-lite/blob/master/docs/_assets/snippets.js
        var snipRange = document.createRange();
        snipRange.selectNodeContents(this.$.code);
        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(snipRange);
        var result = false;
        try {
          result = document.execCommand('copy');
          this.$.copyButton.icon = 'done';
        } catch (err) {
          // Copy command is not available
          Polymer.Base._error(err);
          this.$.copyButton.icon = 'error';
        }

        // Return to the copy button after a second.
        setTimeout(this._resetCopyButtonState.bind(this), 1000);

        selection.removeAllRanges();
        return result;
      },

      _resetCopyButtonState: function() {
        this.$.copyButton.icon = 'content-copy';
      }
    });
  </script>

</dom-module>
